<?php
/*********************************************************************\
 *  Copyright (c) 1998-2013, TH. All Rights Reserved.
 *  FName  :Response.php
 *  Time   :2014/05/13 18:31:40
 *  Remark :api接口的响应类
\*********************************************************************/
class Api_ResponseComment {

    public function __construct() {
        $this->path = array();
        // 此token仅供打卷前台程序调取接口时 验证使用
        $this->_token = '6a1b8e9cae6d0a3a8c3628de74f53ecec4b5735dcb805c57e3e2c3e15fdee643';
    }

    /**
     * @desc ：调用api对应的方法，
     * @param 参数类型
     * @return json
     */
    public function response() {
        // error_reporting(E_ALL);
        $this->timeR1 = microtime_float();
        ignore_user_abort();
        set_time_limit(0);
        $this->process_id = uniqid() . rand(100000, 999999);
        $this->calltime   = time();

        //2019年10月9日 by jeff,防止跨域的错误爆出
        header("Access-Control-Allow-Origin:*");
        header("Access-Control-Allow-Methods: POST, GET");
        header('Access-Control-Allow-Headers:x-requested-with,content-type');
        header('Process-id: ' . $this->process_id);
        header('Connection: close');
        flush();

        if (get_magic_quotes_gpc()) {
            self::strip_magic_quotes($_GET);
            self::strip_magic_quotes($_POST);
        }

        $_PARAMS = array_merge($_GET, $_POST);

        $this->begin(__FUNCTION__);

        set_error_handler(array(&$this, 'error_handle'), E_ERROR);
        set_error_handler(array(&$this, 'user_error_handle'), E_USER_ERROR);

        #加载配置文件获取所有api数组
        if (isset($_PARAMS['version'])) {
            $version = $_PARAMS['version'];
        } else {
            if (isset($_PARAMS['token'])) {
                // 区分是否有token 有token则验证token 且默认版本号为v1
                if ($_PARAMS['token'] == md5($this->_token)) {
                    $version = 'v1';
                } else {
                    $result_json = array(
                        'success' => false,
                        'msg'     => '请求失败，token不匹配！',
                    );
                    echo json_encode($result_json);exit;
                }
            } else {
                $result_json = array(
                    'success' => false,
                    'msg'     => '请求失败，token不存在！',
                );
                echo json_encode($result_json);exit;
            }
        }
        $mapper_file = "Config/config." . $version . ".php";
        if (file_exists($mapper_file)) {
            include $mapper_file;
            $this->certi_key = $CERTI_KEY;
        } else {
            $this->send_user_error('VERSION_NOT_NULL', 'VERSION不匹配');
        }

        //获取处理入口和对应参数
        list($method, $params) = $this->parse_rpc_request($_PARAMS);

        $result = array();
        // 默认返回值格式
        $return_format = 'normal';

        if (isset($api_array) && isset($api_array[$method])) {
            //开始访问接口
            $object = $api_array[$method];
            // 返回值格式
            isset($object['return_format']) && $return_format = $object['return_format'];

            //开始访问接口
            $class  = FLEA::getSingleton($object['class']);
            $result = $class->$object['method']($params, $this);
            $output = $this->end();
        } else {
            $output = $this->end();
            $msg    = '不存在' . $_REQUEST['method'] . '接口';
            $output = $msg;
            $status = 'fail';
        }

        // 默认返回值格式
        $result_json = array(
            'rsp'  => $status ? $status : 'succ',
            'data' => $result,
            'res'  => strip_tags($output),
        );

        // $this->rpc_response_end($result, $this->process_id, $result_json);
        echo json_encode($result_json);
    }

    /**
     * 处理参数信息
     * Time：2017/04/26 09:02:38
     * @author li
     */
    private function parse_rpc_request($request) {
        if (!isset($request['method'])) {
            $this->send_user_error('ERROR_METHOD_NULL', 'Method 不存在');
            return false;
        }

        $sign = $request['sign'];
        unset($request['sign']);
        $self_sign = $this->gen_sign($request);
        /*if($self_sign != $sign){
        $this->send_user_error('SIGN_ERROR', '签名错误');
        return false;
        }*/

        //获取method
        $method      = $request['method'];
        $array_unset = array('method', 'version');
        foreach ($variable as $pk) {
            unset($request[$pk]);
        }

        return array($method, $request);
    }

    /**
     * 签名处理
     * Time：2017/04/26 09:02:38
     * @author li
     */
    private function gen_sign($params) {
        $str_key_value = $this->assemble($params);
        return strtoupper(md5(strtoupper(md5($str_key_value)) . $this->certi_key));
    }

    /**
     * 字符串处理
     * Time：2017/04/26 09:02:38
     * @author li
     */
    private function assemble($params) {
        if (!is_array($params)) {
            return null;
        }

        ksort($params, SORT_STRING);
        $sign = '';
        foreach ($params AS $key => $val) {
            if (is_null($val)) {
                continue;
            }

            if (is_bool($val)) {
                $val = ($val) ? 'true' : 'false';
            }

            $sign .= $key . (is_array($val) ? $this->assemble($val) : $val);
        }
        return $sign;
    }

    /**
     * 处理传递的参数
     * Time：2017/04/26 09:02:38
     * @author li
     */
    public function strip_magic_quotes(&$var) {
        foreach ($var as $k => $v) {
            if (is_array($v)) {
                self::strip_magic_quotes($var[$k]);
            } else {
                $var[$k] = stripcslashes($v);
            }
        }
    }

    private function begin() {

    }

    private function end($shutdown = false) {

    }

    public function shutdown() {
        $this->end(true);
    }

    private function rpc_response_end($result, $process_id, $result_json) {
        if (isset($process_id) && $process_id) {
            #更新日志信息
            $model = FLEA::getSingleton('Model_Api_Logs');
            $sql   = "SELECT apilog_id from api_logs where rpc_id='{$process_id}' limit 0,1";
            $row   = $model->findBySql($sql);
            if ($row) {
                $row = $row[0];
                switch ($result_json['rsp']) {
                case 'succ':
                    $status = "success";
                    break;
                case 'fail':
                    $status = "fail";
                    break;
                }

                $data = array(
                    'apilog_id'     => $row['apilog_id'],
                    'msg'           => $result_json['res'],
                    'response_json' => json_encode($result_json),
                    'createtime'    => time(),
                    'status'        => $status,
                );

                $model->update($data);
            }
        }

    }

    public function error_handle($error_code, $error_msg) {
        $this->send_user_error('4007', $error_msg);
    }

    public function user_error_handle($error_code, $error_msg) {
        $this->send_user_error('4007', $error_msg);
    }

    public function send_user_error($code, $data) {

        $this->end();
        $res = array(
            'rsp'  => 'fail',
            'res'  => $code,
            'data' => $data,
        );

        $this->rpc_response_end($data, $this->process_id, $res);
        echo json_encode($res);
        exit;
    } //End Function
}